<?php
// Checksum calculation function
function icmpChecksum($data) {
    if (strlen($data) % 2) {
        $data .= "\x00";
    }

    $bit = unpack('n*', $data);
    $sum = array_sum($bit);

    while ($sum >> 16) {
        $sum = ($sum >> 16) + ($sum & 0xffff);
    }

    return pack('n*', ~$sum);
}

/* ICMP ping packet with a pre-calculated checksum */
function ping($host, $timeout = 1) {
    // Making the package
    $type = "\x08";
    $code = "\x00";
    $checksum = "\x00\x00";
    $identifier = "\x00\x00";
    $seqNumber = "\x00\x00";
    $data= "Scarface";
    $package = $type.$code.$checksum.$identifier.$seqNumber.$data;
    $checksum = icmpChecksum($package); // Calculate the checksum
    $package = $type.$code.$checksum.$identifier.$seqNumber.$data;

    // And off to the sockets
    $socket = socket_create(AF_INET, SOCK_RAW, 1);
    socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => $timeout, 'usec' => 0));
    socket_connect($socket, $host, null);

    $result = false;
    $startTime = microtime(true);
    socket_send($socket, $package, strLen($package), 0);
    if (socket_read($socket, 255)) {
        $result = round(microtime(true) - $startTime, 4) .' seconds';
    }
    socket_close($socket);

    return $result;
}

// Function to check response time
function pingDomain($host, $port = 80) {
    $startTime = microtime(true);
    $file = fsockopen($host, $port, $errno, $errstr, 10);
    $stopTime = microtime(true);
    $status = 0;

    if (!$file) {
        $status = -1;  // Site is down
    } else {
        fclose($file);
        $status = ($stopTime - $startTime) * 1000;
        $status = floor($status);
    }

    return $status;
}
?>

<!DOCTYPE html>
<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  <title>Ping</title>
  <meta name="description" content="Online Ping" />
  <meta name="author" content="Roger Xu" />

  <style>
    @import "http://ajax.googleapis.com/ajax/libs/dojo/1.6.0/dojo/resources/dojo.css";
    @import "http://ajax.googleapis.com/ajax/libs/dojo/1.6.0/dijit/themes/claro/claro.css";
  </style>
</head>
<body class="claro">

  <h1>Ping</h1>
  <h2 id="version">Unknown Version</h2>

  <form id="pingForm" data-dojo-type="dijit.form.Form" method="get" action="">
    <select id="host" name="host" data-dojo-type="dijit.form.ComboBox" data-dojo-props='name:"host"' style="width: 200px;">
      <option value="rogerxu-opm.appspot.com:80">rogerxu-opm.appspot.com:80</option>
      <option value="server4.operamini.com:80">server4.operamini.com:80</option>
      <option value="mini5.opera-mini.net:80" selected="selected">mini5.opera-mini.net:80</option>
      <option value="demo.opera-mini.net:9002">demo.opera-mini.net:9002</option>
      <option value="google-cust.opera-mini.net:80">google-cust.opera-mini.net:80</option>
      <option value="p09-15.opera-mini.net:80">p09-15.opera-mini.net:80</option>
      <option value="global-4-lvs-usa.opera-mini.net:80">global-4-lvs-usa.opera-mini.net:80</option>
      <option value="r01-15.opera-mini.net:80">r01-15.opera-mini.net:80</option>
      <option value="r03-15.opera-mini.net:80">r03-15.opera-mini.net:80</option>
    </select>
    <input id="port" name="port" type="text" value="" data-dojo-type="dijit.form.NumberTextBox" style="width: 80px;" data-dojo-props='name:"port", required:true, constraints:{min:1,max:65535,places:0}, missingMessage:"Please enter a port number.", invalidMessage:"Invalid port number.", style:"width:80px;" ' />
    <input id="submit" type="submit" value="Ping!" data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit", label:"Ping!"' />
    <input id="reset" type="reset" value="Reset" data-dojo-type="dijit.form.Button" data-dojo-props='type:"reset", label:"Reset"' />
  </form>

<?php
if ($_SERVER['REQUEST_METHOD'] == 'GET' && empty($_GET) === false) {
    print_r($_GET);
    echo '<br />' . "\n";

    $status = pingDomain($_GET['host'], $_GET['port']);
    $site = 'http://' . $_GET['host'] . ':' . $_GET['port'] . '/';
    if ($status === -1) {
        echo "<strong>$site</strong> is DOWN.";
    } else {
        echo "<strong>$site</strong> is ALIVE (<strong>$status</strong> ms).";
    }
}
?>

<script src="https://ajax.googleapis.com/ajax/libs/dojo/1.6.0/dojo/dojo.xd.js.uncompressed.js" data-dojo-config='parseOnLoad: true, isDebug: true, locale: "en"'></script>
<script>
    dojo.require("dojo.date.locale");
    dojo.require("dojo.parser");

    dojo.require("dijit.dijit"); // optimize: load dijit layer
    dojo.require("dijit.ColorPalette");
    dojo.require("dijit.Dialog");
    dojo.require("dijit.Editor");
    dojo.require("dijit.InlineEditBox");
    dojo.require("dijit.Menu");
    dojo.require("dijit.TitlePane");
    dojo.require("dijit.Toolbar");
    dojo.require("dijit.ToolbarSeparator");
    dojo.require("dijit.TooltipDialog");

    dojo.require("dijit.form.Button");
    dojo.require("dijit.form.CheckBox");
    dojo.require("dijit.form.ComboBox");
    dojo.require("dijit.form.DateTextBox");
    dojo.require("dijit.form.DropDownButton");
    dojo.require("dijit.form.FilteringSelect");
    dojo.require("dijit.form.Form");
    dojo.require("dijit.form.NumberSpinner");
    dojo.require("dijit.form.NumberTextBox");
    dojo.require("dijit.form.RadioButton");
    dojo.require("dijit.form.SimpleTextarea");
    dojo.require("dijit.form.Textarea");
    dojo.require("dijit.form.TextBox");
    dojo.require("dijit.form.ToggleButton");
    dojo.require("dijit.form.ValidationTextBox");

    dojo.require("dijit.layout.BorderContainer");
    dojo.require("dijit.layout.ContentPane");

    dojo.require("dojox.data.AndOrWriteStore");
    dojo.require("dojox.html.entities");

    dojo.require("dojox.layout.FloatingPane");
    dojo.require("dojox.layout.ResizeHandle");
    dojo.require("dojox.storage");
    dojo.require("dojox.validate");
    dojo.require("dojox.validate.web");
    dojo.require("dojox.widget.Standby");
    dojo.require("dojox.widget.Toaster");
</script>
<!-- dojo ready -->
<script>
dojo.ready(function() {
    dojo.byId('version').innerHTML = 'Version ' + dojo.version;

    var selector = dijit.byId('host');
    dojo.connect(selector, 'onChange', function(newValue) {
        var selector = dijit.byId('host');
        var store = selector.store;

        var selectedItem = selector.get('item');
        if (selectedItem) {
            var selectedValue = store.getValue(selectedItem, 'value');
            newValue = selectedValue;
        }

        var parts = newValue.split(':');

        if (parts.length > 1) {
            var domain = parts[0];
            var port = parts[1];

            dijit.byId('host').set('value', domain);
            dijit.byId('port').set('value', port);
        }
    });

    var form = dijit.byId('pingForm');
    dojo.connect(form, 'onSubmit', function(e) {
        if (form.validate()) {
            return true;
        } else {
            return false;
        }
    });
});
</script>
</body>
</html>

